package icraf.carbon.gui;

import icraf.carbon.core.Details;
import icraf.carbon.gui.LCTableModel.DisplayType;
import icraf.carbon.gui.MenuFactory.MenuProperty;
import icraf.common.gui.ExcelAdapter;
import icraf.common.gui.MenuAdapter;
import icraf.common.gui.MenuGenerator;
import icraf.common.gui.TableRowHeaderRenderer;
import icraf.common.gui.VerticalTableHeaderCellRenderer;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;

import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

//TODO: tambahin generic type ke table model nya ex: <M extends MatrixTableModel>

public class MatrixPanel extends JPanel {
	class DoubleRenderer extends DefaultTableCellRenderer {
		private static final long serialVersionUID = -6699250896651787537L;

		public DoubleRenderer() {
			super();
		}

		@Override
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			JLabel rend = (JLabel) super.getTableCellRendererComponent(table,
					value, isSelected, hasFocus, row, column);
			double d = (value == null) ? 0 : ((Double) value).doubleValue();
			String text = "";
			if ((value != null) && !((Double) value).isNaN()) {
				text = formatValue(d);
			}
			rend.setText(text);
			rend.setHorizontalAlignment(SwingConstants.RIGHT);
			if (!isSelected) {
				if (isDiagonalColor && (row == column)) {
					rend.setBackground(diagonalColor);
				} else if (isRowColor && row % 2 > 0) {
					rend.setBackground(backgroundRow);
				} else {
					rend.setBackground(backgroundDefault);
				}
				TableModel m = table.getModel();
				HashSet<Integer> highlightRows = null;
				if (m instanceof MatrixTableModel) {
					highlightRows = ((MatrixTableModel) m).getHighlightRows();
				}
				if (highlightRows != null && highlightRows.size() > 0) {
					if (highlightRows.contains(row)) {
						rend.setBackground(((MatrixTableModel) m)
								.getHighlightRowColor());
					}
				}
			}
			if (isTotalFields) {
				if (!isSelected) {
					if (row == table.getRowCount() - 1) {
						if (column == table.getColumnCount() - 1) {
							rend.setBackground(backgroundTotal2);
						} else {
							rend.setBackground(backgroundTotal);
						}
					} else if (column == table.getColumnCount() - 1) {
						rend.setBackground(backgroundTotal);
					}

				}
			}
			rend.setToolTipText(Float.toString((float) d));
			return rend;
		}

	}

	public class Listener extends MouseAdapter implements ActionListener,
			TableModelListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (MenuProperty.EDIT_COPY.isAction(e)) {
				copy();
			} else if (MenuProperty.EDIT_PASTE.isAction(e)) {
				paste();
			} else if (MenuProperty.EDIT_COPY_TABLE.isAction(e)) {
				copyTable();
			} else if (MenuProperty.EDIT_DELETE.isAction(e)) {
				clearSelectedCells();
			} else if (MenuProperty.EDIT_DETAIL.isAction(e)) {
				showInfo();
			} else if (e.getSource().equals(unitCB)) {
				updateUnit();
			} else if (MenuProperty.GENERAL_VIEW_FORM.isAction(e)) {
				showFormView();
			}

		}

		@Override
		public void mousePressed(MouseEvent e) {
			updateRowHeader();
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger()||e.isControlDown()||e.getButton()==MouseEvent.BUTTON3) {
				if (e.getSource().equals(table)) {
					popMenu.show((Component) e.getSource(), e.getX(), e.getY());
				} else if (e.getSource().equals(cornerPanel)) {
					popMenuCorner.show((Component) e.getSource(), e.getX(),
							e.getY());
				}
			}
			updateRowHeader();
		}

		@Override
		public void tableChanged(TableModelEvent e) {
			updateColumnHeader();

			rowHeader.repaint();
			scrollMatrix.repaint();

			updateCornerInfo();
			if (e.getType() == TableModelEvent.UPDATE) {
				updateHighlight();
			}
			updateRowHeader();
		}

	}

	class StringRenderer extends DefaultTableCellRenderer {
		private static final long serialVersionUID = -6699250896651787537L;

		public StringRenderer() {
			super();
		}

		@Override
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			JLabel rend = (JLabel) super.getTableCellRendererComponent(table,
					value, isSelected, hasFocus, row, column);
			if (value instanceof String) {
				String text = (value == null) ? "" : (String) value;
				rend.setText(text);
			} else if (value instanceof Integer) {
				String text = (value == null) ? "" : formatter
						.format((Integer) value);
				rend.setText(text);
				rend.setHorizontalAlignment(SwingConstants.RIGHT);
			}

			if (!isSelected) {
				if (isRowColor && row % 2 > 0) {
					rend.setBackground(backgroundRow);
				} else {
					rend.setBackground(backgroundDefault);
				}

				TableModel m = table.getModel();
				HashSet<Integer> highlightRows = null;
				if (m instanceof MatrixTableModel) {
					highlightRows = ((MatrixTableModel) m).getHighlightRows();
				}
				if (highlightRows != null && highlightRows.size() > 0) {
					if (highlightRows.contains(row)) {
						rend.setBackground(((MatrixTableModel) m)
								.getHighlightRowColor());
					}
				}
			}
			return rend;
		}

	}

	public static String MATRIX_VIEW = "matrix", FORM_VIEW = "form";

	private static final long serialVersionUID = -6463132134870077766L;

	private Color backgroundDefault = Color.white;
	private Color backgroundRow = new Color(235, 230, 255);
	private Color backgroundTotal = new Color(200, 200, 255);
	private Color backgroundTotal2 = new Color(150, 150, 255);
	private CardLayout card;

	private JPanel cornerPanel = new JPanel();
	private Color diagonalColor = new Color(250, 240, 200);
	private DecimalFormat formatter = (DecimalFormat) NumberFormat
			.getNumberInstance();
	
	private DecimalFormat formatterDef = (DecimalFormat) NumberFormat
			.getNumberInstance();

	private boolean isDiagonalColor = false;
	private boolean isMenuDetail;
	private boolean isRowColor = true;
	private boolean isShowCornerInfo = false;
	private boolean isTotalFields = false;

	private boolean isUnitSelectable;
	private boolean isVerticalHeader = false;
	private boolean isZoneAreaScale = false;
	private Listener listener = new Listener();
	private MatrixFormPanel matrixFormPanel;
	private MatrixTableModel matrixTableModel;
	private JMenuItem menuDetail;
	private String menuDetailTitle;
	private JPopupMenu popMenu = new JPopupMenu();
	private JPopupMenu popMenuCorner = new JPopupMenu();
	private JList<Object> rowHeader;
	private RowHighlight rowHighlight;
	private JScrollPane scrollMatrix;
	private StringSelection stsel;
	private Clipboard system;
	private JTable table;
	private JLabel totalLabel = new JLabel();
	private String unitArea = "";
	protected JComboBox<String> unitCB = new JComboBox<String>();
	private JPanel unitCornerPanel;
	private String unitDefault = "";

	private JLabel unitLabel = new JLabel();

	private DefaultComboBoxModel<String> unitModelCB = new DefaultComboBoxModel<String>();

	private double valueTotal = 0;

	private TableRowHeaderRenderer rowHeaderRenderer;
	private ArrayList<MatrixPanelListener> matrixPanelListeners = new ArrayList<MatrixPanelListener>();
	private MenuAdapter[] menuToolBar = { MenuProperty.EDIT_COPY, MenuProperty.EDIT_PASTE,null, MenuProperty.EDIT_COPY_TABLE};

	public MatrixPanel(MatrixTableModel tableModel) {
		matrixTableModel = tableModel;
		init();
	}

	public MatrixPanel(MatrixTableModel tableModel, boolean isVerticalHeader,
			boolean isShowCornerInfo, boolean isDiagonalHighlight,
			boolean isTotalField, boolean isZoneAreaScale) {
		matrixTableModel = tableModel;
		this.isVerticalHeader = isVerticalHeader;
		this.isShowCornerInfo = isShowCornerInfo;
		this.isDiagonalColor = isDiagonalHighlight;
		this.isTotalFields = isTotalField;
		this.isZoneAreaScale = isZoneAreaScale;
		init();
	}

	protected void clearSelectedCells() {
		for (int r : table.getSelectedRows()) {
			for (int c : table.getSelectedColumns()) {
				matrixTableModel.setValueAt(0d, r, c);
			}
		}

	}
	
	public JToolBar generateToolbarMenu(JToolBar toolBar) {
		return MenuGenerator.createMenuItem(toolBar, menuToolBar, listener);
	}

	public void copy() {
		for(MatrixPanelListener l: matrixPanelListeners) {
			l.startCopy(this);
		}
		StringBuffer sbf = new StringBuffer();
		// Check to ensure we have selected only a contiguous block of
		// cells
		int numcols = table.getSelectedColumnCount();
		int numrows = table.getSelectedRowCount();
		int[] rowsselected = table.getSelectedRows();
		int[] colsselected = table.getSelectedColumns();
		if (!((numrows - 1 == rowsselected[rowsselected.length - 1]
				- rowsselected[0] && numrows == rowsselected.length) && (numcols - 1 == colsselected[colsselected.length - 1]
				- colsselected[0] && numcols == colsselected.length))) {
			JOptionPane.showMessageDialog(null,  MenuProperty.EDIT_COPY_ERROR.getAccessibleDescription(),
					MenuProperty.EDIT_COPY_ERROR.getLabel(), JOptionPane.ERROR_MESSAGE);
			return;
		}
		for (int i = 0; i < numrows; i++) {
			for (int j = 0; j < numcols; j++) {
				Object val = table.getValueAt(rowsselected[i], colsselected[j]);
				String strVal = val.toString();
				if(val instanceof Double) {
					strVal = formatterDef.format(val);
				}
				sbf.append(strVal);
				if (j < numcols - 1)
					sbf.append("\t");
			}
			sbf.append("\n");
		}
		stsel = new StringSelection(sbf.toString());
		system = Toolkit.getDefaultToolkit().getSystemClipboard();
		system.setContents(stsel, stsel);
		
		for(MatrixPanelListener l: matrixPanelListeners) {
			l.endCopy(this);
		}
	}

	public void copyTable() {
		StringBuffer sbf = new StringBuffer();
		int numcols = table.getColumnCount();
		int numrows = table.getRowCount();
		sbf.append("\t");
		for (int j = 0; j < numcols; j++) {
			sbf.append(table.getColumnName(j));
			if (j < numcols - 1)
				sbf.append("\t");
		}
		sbf.append("\n");
		for (int i = 0; i < numrows; i++) {
			sbf.append(rowHeader.getModel().getElementAt(i)).append("\t");
			for (int j = 0; j < numcols; j++) {
				//sbf.append(table.getValueAt(i, j));
				Object val = table.getValueAt(i, j);
				String strVal = val.toString();
				if(val instanceof Double) {
					strVal = formatterDef.format(val);
				}
				sbf.append(strVal);
								
				if (j < numcols - 1)
					sbf.append("\t");
			}
			sbf.append("\n");
		}
		stsel = new StringSelection(sbf.toString());
		system = Toolkit.getDefaultToolkit().getSystemClipboard();
		system.setContents(stsel, stsel);
	}

	public String formatValue(double d) {
		d = (d == 0) ? 0 : d;
		if (Math.abs(d) < 0.0001) {
			formatter.setMaximumFractionDigits(6);
		} else if (Math.abs(d) < 1) {
			formatter.setMaximumFractionDigits(4);
		} else if (Math.abs(d) < 100) {
			formatter.setMaximumFractionDigits(2);
		} else if (Math.abs(d) < 10000) {
			formatter.setMaximumFractionDigits(1);
		} else {
			formatter.setMaximumFractionDigits(0);
		}
		return formatter.format(d);
	}

	public MatrixTableModel getMatrixTableModel() {
		return matrixTableModel;
	}

	public JPopupMenu getPopMenu() {
		return popMenu;
	}

	public JList<?> getRowHeader() {
		return rowHeader;
	}

	public JTable getTable() {
		return table;
	}

	public String getUnitArea() {
		return unitArea;
	}

	public double getValueTotal() {
		return valueTotal;
	}

	private void init() {
		this.setLayout(new BorderLayout());
		formatterDef.setMaximumFractionDigits(32);
		// matrixTableModel.addTableModelListener(tableModelListener);
		matrixTableModel.addTableModelListener(listener);

		table = new JTable(matrixTableModel);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table.setGridColor(backgroundRow);
		table.setShowHorizontalLines(!isVerticalHeader);
		table.setRowHeight(20);
		table.getTableHeader().setReorderingAllowed(false);

		scrollMatrix = new JScrollPane(table);

		card = new CardLayout();
		this.setLayout(card);
		this.add(scrollMatrix, MATRIX_VIEW);

		// Use a JList as a RowHeader for the scroll pane
		rowHeader = new JList<Object>(matrixTableModel.getRowHeaderModel());
		rowHeader.setFixedCellHeight(table.getRowHeight());
		rowHeaderRenderer = new TableRowHeaderRenderer(
				table);
		rowHeaderRenderer.setTotalFields(isVerticalHeader);
		rowHeader.setCellRenderer(rowHeaderRenderer);
		rowHeader.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (table.getRowCount() == 0)
					return;
				int index = rowHeader.locationToIndex(e.getPoint());
				rowHeader.setSelectedIndex(index);
				table.setRowSelectionInterval(index, index);
				table.requestFocus();
			}
		});
		rowHeader.setBackground(this.getBackground());

		scrollMatrix.setRowHeaderView(rowHeader); // Adds row-list left of the
		// table
		table.setDefaultRenderer(Double.class, new DoubleRenderer());
		table.setDefaultRenderer(String.class, new StringRenderer());
		table.setDefaultRenderer(Integer.class, new StringRenderer());
		table.setDefaultEditor(Double.class, new DoubleCellEditor());

		new ExcelAdapter(table);

		table.getInputMap().put(KeyStroke.getKeyStroke("DELETE"), "delete");
		table.getActionMap().put("delete", new AbstractAction() {
			private static final long serialVersionUID = -3884027154884332834L;

			@Override
			public void actionPerformed(ActionEvent e) {
				clearSelectedCells();
			}
		});

		table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		table.setRowSelectionAllowed(true);
		table.setColumnSelectionAllowed(true);
		table.setCellSelectionEnabled(true);

		popMenu.add(MenuGenerator.createMenuItem(MenuProperty.EDIT_COPY,
				listener));
		popMenu.add(MenuGenerator.createMenuItem(MenuProperty.EDIT_PASTE,
				listener));
		popMenu.addSeparator();
		popMenu.add(MenuGenerator.createMenuItem(MenuProperty.EDIT_COPY_TABLE,
				listener));
		popMenu.addSeparator();

		menuDetail = MenuGenerator.createMenuItem(MenuProperty.EDIT_DETAIL,
				listener);

		table.addMouseListener(listener);

		initCorner();
		setShowCornerInfo(isShowCornerInfo);
	}

	private void initCorner() {
		// cornerPanel.setLayout(new BoxLayout(cornerPanel,
		// BoxLayout.PAGE_AXIS));
		cornerPanel.setLayout(new BorderLayout());
		Font f = unitLabel.getFont().deriveFont(Font.BOLD);
		// unitLabel.setFont(f);
		totalLabel.setFont(f);
		// unitCB.setFont(f);

		unitCornerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2,2));
		//TODO:label!
		JLabel l1 = new JLabel(MenuProperty.CHART_AXIS_UNIT.getLabel() + ":");
		l1.setFont(f);
		unitCornerPanel.add(l1);
		unitLabel.setText(unitDefault);
		unitCornerPanel.add(unitLabel);

		JButton b = MenuFactory.createButtonIcon(
				MenuProperty.GENERAL_VIEW_FORM, listener);
		JToolBar pb = new JToolBar();
		pb.setLayout(new FlowLayout(FlowLayout.CENTER, 0,0));
		pb.setFloatable(false);
		pb.add(b);

		JPanel p = new JPanel(new FlowLayout(FlowLayout.CENTER, 2,2));
		JLabel l2 = new JLabel("TOTAL:");
		l2.setFont(f);
		p.add(l2);
		p.add(totalLabel);

		cornerPanel.add(unitCornerPanel, BorderLayout.NORTH);
		cornerPanel.add(p);
		cornerPanel.add(pb, BorderLayout.SOUTH);

		popMenuCorner.add(MenuGenerator.createMenuItem(MenuProperty.EDIT_COPY,
				new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						stsel = new StringSelection(formatValue(getValueTotal()));
						system = Toolkit.getDefaultToolkit()
								.getSystemClipboard();
						system.setContents(stsel, stsel);
					}
				}));
		popMenuCorner.addSeparator();
		popMenuCorner.add(MenuGenerator.createMenuItem(
				MenuProperty.GENERAL_VIEW_FORM, listener));
		cornerPanel.addMouseListener(listener);
		
		unitModelCB.addElement(unitDefault);
		unitModelCB.addElement(unitArea);
		unitCB.setModel(unitModelCB);
		unitCB.addActionListener(listener);
	}

	public boolean isDiagonalColor() {
		return isDiagonalColor;
	}

	public boolean isRowColor() {
		return isRowColor;
	}

	public boolean isShowCornerInfo() {
		return isShowCornerInfo;
	}

	public boolean isTotalFields() {
		return isTotalFields;
	}

	public boolean isVerticalHeader() {
		return isVerticalHeader;
	}

	public boolean isZoneAreaScale() {
		return isZoneAreaScale;
	}

	public void paste() {
		for(MatrixPanelListener l: matrixPanelListeners) {
			l.startPaste(this);
		}
		
		if (matrixTableModel instanceof LCTableModel) {
			LCTableModel m = (LCTableModel)matrixTableModel;
			if(m.getValueScale()==0 || m.getProject().getZoneList().get(m.getZoneIndex()).getAreaSize()==0) {
				JOptionPane.showMessageDialog(this, MenuProperty.PROJECT_ZONE_MATRIX_ZERO_ERROR.getAccessibleDescription(),
						MenuProperty.PROJECT_ZONE_MATRIX_ZERO_ERROR.getLabel(), JOptionPane.ERROR_MESSAGE);
				return;
			}
		}
			
		
		if ((table.getSelectedRows().length == 0)
				|| (table.getSelectedColumns().length == 0))
			return;
		system = Toolkit.getDefaultToolkit().getSystemClipboard();
		int startRow = (table.getSelectedRows())[0];
		int startCol = (table.getSelectedColumns())[0];
		try {
			String trstring = (String) (system.getContents(this)
					.getTransferData(DataFlavor.stringFlavor));
			String lineStr[] = trstring.split("\n");
			for (int i = 0; i < lineStr.length; i++) {
				String val[] = lineStr[i].split("\t");
				for (int j = 0; j < val.length; j++) {
					if (startRow + i < table.getRowCount()
							&& startCol + j < table.getColumnCount())
						table.setValueAt(val[j], startRow + i, startCol + j);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		
		for(MatrixPanelListener l: matrixPanelListeners) {
			l.endPaste(this);
		}
	}

	public void setCornerSetting(String unitDef, String unitArea,
			boolean isUnitSelectable) {
		setUnit(unitDef, unitArea);
		setUnitSelectable(isUnitSelectable);
	}

	public void setDiagonalColor(boolean isDiagonalColor) {
		this.isDiagonalColor = isDiagonalColor;
	}

	public void setMenuDetail(boolean b, String title) {
		menuDetailTitle = title;
		isMenuDetail = b;
		if (b) {
			popMenu.add(menuDetail);
		} else {
			popMenu.remove(menuDetail);
		}
	}

	public void setRowColor(boolean isRowColor) {
		this.isRowColor = isRowColor;
	}

	public void setRowHighlight(boolean b, RowHighlight rowHighlight) {
		this.rowHighlight = rowHighlight;
		updateHighlight();
	}

	public void setShowCornerInfo(boolean showCornerInfo) {
		this.isShowCornerInfo = showCornerInfo;
		if (showCornerInfo) {
			JScrollPane scrollP = new JScrollPane(cornerPanel);
			scrollP.setBorder(null);
			scrollMatrix.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER,scrollP);
		} else {
			scrollMatrix.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, null);
		}
	}

	public void setTotalFields(boolean isTotalFields) {
		this.isTotalFields = isTotalFields;
	}

	public void setUnit(String unitDefault, String unitArea) {
		this.unitDefault = unitDefault;
		this.unitArea = unitArea;
		unitLabel.setText(unitDefault);
		unitModelCB.removeAllElements();
		unitModelCB.addElement(unitDefault);
		unitModelCB.addElement(unitArea);
	}

	public void setUnitSelectable(boolean isUnitSelectable) {
		this.isUnitSelectable = isUnitSelectable;
		if (isUnitSelectable) {
			unitCornerPanel.remove(unitLabel);
			unitCornerPanel.add(unitCB);
		} else {
			unitCornerPanel.remove(unitCB);
			unitCornerPanel.add(unitLabel);
		}
	}
	
	public void setSelectUnitArea(boolean b) {
		if(b) {
			unitCB.setSelectedIndex(1);
		} else {
			unitCB.setSelectedIndex(0);
		}
		updateUnit();
		matrixTableModel.fireTableDataChanged();
	}
	
	public boolean isSelectUnitArea() {
		return	unitCB.getSelectedIndex()==1;
	}

	public void setVerticalHeader(boolean isVerticalHeader) {
		this.isVerticalHeader = isVerticalHeader;
	}

	public void setZoneAreaScale(boolean isZoneAreaScale) {
		this.isZoneAreaScale = isZoneAreaScale;
	}

	public void showFormView() {
		if (!(matrixTableModel instanceof LCTableModel))
			return;
		if (matrixFormPanel == null) {
			LCTableModel m = (LCTableModel) matrixTableModel;
			matrixFormPanel = new MatrixFormPanel(this, m);
			matrixFormPanel.setUnitSelectable(isUnitSelectable);
			matrixFormPanel.setUnit(unitDefault, unitArea);
			if (isMenuDetail)
				matrixFormPanel.setMenuDetail(isMenuDetail, menuDetailTitle);
			this.add(matrixFormPanel, FORM_VIEW);
		}
		matrixFormPanel.updateDisplay();
		card.show(this, FORM_VIEW);
	}

	public void showInfo() {
		if (!(table.getModel() instanceof LCTableModel))
			return;
		int numcols = table.getSelectedColumnCount();
		int numrows = table.getSelectedRowCount();
		if (numcols == 0)
			return;
		int[] rowsselected = table.getSelectedRows();
		int[] colsselected = table.getSelectedColumns();
		if (!((numrows - 1 == rowsselected[rowsselected.length - 1]
				- rowsselected[0] && numrows == rowsselected.length) && (numcols - 1 == colsselected[colsselected.length - 1]
				- colsselected[0] && numcols == colsselected.length))) {
			JOptionPane.showMessageDialog(null, MenuProperty.EDIT_SELECT_ERROR.getAccessibleDescription(),
					MenuProperty.EDIT_SELECT_ERROR.getLabel(), JOptionPane.ERROR_MESSAGE);
			return;
		}
		Point p = this.getLocationOnScreen();
		int x = p.x;
		int y = p.y;
		for (int i = 0; i < numrows; i++) {
			for (int j = 0; j < numcols; j++) {
				int r = rowsselected[i];
				int c = colsselected[j];
				LCTableModel m = (LCTableModel) table.getModel();
				Details details = m.getDetail(r, c);
				if (details == null || details.equals(""))
					continue;
				String z = m.getProject().getZoneList().get(m.getZoneIndex())
						.getLabel();
				// TODO:ini harus refers ke LC nya langsung aja!
				String label = "[" + z + "] From \""
						+ details.getLandCover1().getLabel() + "\" to \""
						+ details.getLandCover2().getLabel() + "\"";
				DetailPanel n = new DetailPanel(menuDetailTitle, label, details);
				n.setHighlightedRow(details.getHighlightRows());
				JDialog d = n.createDialog((Window) this.getRootPane()
						.getParent(), null);
				d.setLocation(x, y);
				x += 10;
				y += 10;
			}
		}
	}

	public void showMatrixView() {
		card.show(this, MATRIX_VIEW);
	}

	public void updateColumnHeader() {
		if (isVerticalHeader) {
			VerticalTableHeaderCellRenderer headerRenderer = new VerticalTableHeaderCellRenderer();
			VerticalTableHeaderCellRenderer headerRenderer2 = new VerticalTableHeaderCellRenderer();
			headerRenderer2.setOpaque(true);
			headerRenderer2.setBackground(backgroundTotal2);
			Enumeration<TableColumn> columns = table.getColumnModel()
					.getColumns();
			while (columns.hasMoreElements()) {
				TableColumn col = columns.nextElement();
				if (col.getModelIndex() == (table.getColumnCount() - 1)
						&& isTotalFields) {
					col.setHeaderRenderer(headerRenderer2);
				} else {
					col.setHeaderRenderer(headerRenderer);
				}
				col.setPreferredWidth(60);
			}
		}
	}

	public void updateCornerInfo() {
		if (!isShowCornerInfo)
			return;
		if (matrixTableModel instanceof LCTableModel) {
			valueTotal = ((LCTableModel) matrixTableModel).getValueTotal();

			totalLabel.setText(formatValue(valueTotal));
			
		}
		
		
	}

	public void updateHighlight() {
		if (matrixTableModel instanceof LCTableModel) {
			if (((LCTableModel) matrixTableModel).getDisplayType() == DisplayType.FORM_VIEW)
				return;
		}
		MatrixTableModel m = matrixTableModel;
		if (rowHighlight == null)
			return;
		m.setHighlightRowColor(rowHighlight.getColor());
		m.getHighlightRows().clear();
		int t = isTotalFields() ? 1 : 0;
		for (int r = 0; r < m.getRowCount() - t; r++) {
			double n = 0;
			if(isTotalFields()) {
				n = (Double)m.getValueAt(r, m.getColumnCount() -1);
			} else {
				for (int c = 0; c < m.getColumnCount(); c++) {
					Double d = (Double) m.getValueAt(r, c);
					if (d != null)
						n += d;
				}
			}
			if (rowHighlight.isHighlight(matrixTableModel, r, n)) {
				m.getHighlightRows().add(r);
			}
		}

	}

	private void updateRowHeader() {
		rowHeader.setSelectedIndices(table.getSelectedRows());
		// TODO: pilih column header juga!

	}

	private void updateUnit() {
		if (matrixTableModel instanceof LCTableModel) {
			LCTableModel m = (LCTableModel) matrixTableModel;
			m.setAreaScale(unitCB.getSelectedIndex() == 1, isZoneAreaScale);
		}

	}

	public void addMatrixPanelListeners(MatrixPanelListener l) {
		matrixPanelListeners.add(l);
	}
	
	public void removeMatrixPanelListeners(MatrixPanelListener l) {
		matrixPanelListeners.remove(l);
	}
	
//	private void importFromExcellFile(File file)  {
//		Workbook workbook = null;
//		WritableWorkbook wb;
//		try {
//			workbook = Workbook.getWorkbook(file);
//		} catch (Exception e) {
//			// e.printStackTrace();
//		}
//
//		if (workbook == null) {
//			return;
//		}
//		Sheet[] sheets = workbook.getSheets();
//		Cell c = sheets[0].getCell(0, 0);
//
//	}
}
